package com.bowlong.util;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;

@SuppressWarnings("serial")
public class MultimapLock<K, V> implements Cloneable, Serializable {

	final Map<K, Set<V>> map = new HashMap<>();

	public synchronized int size() {
		return map.size();
	}

	public synchronized boolean isEmpty() {
		return map.isEmpty();
	}

	public synchronized boolean containsKey(Object key) {
		return map.containsKey(key);
	}

	public synchronized boolean contains(K key, V value) {
		Set<V> vals = map.get(key);
		if (vals == null || vals.isEmpty())
			return false;
		return vals.contains(value);
	}

	public synchronized Set<V> get(K key) {
		Set<V> v = map.get(key);
		if (v == null) {
			v = new HashSet<V>();
			map.put(key, v);
		}
		return v;
	}

	public synchronized List<V> getToList(K key) {
		Set<V> v = map.get(key);
		if (v == null) {
			v = new HashSet<V>();
			map.put(key, v);
		}
		return new Vector<V>(v);
	}

	public synchronized V put(K key, V value) {
		Set<V> v = map.get(key);
		if (v == null) {
			v = new HashSet<V>();
			map.put(key, v);
		}
		v.add(value);
		return value;
	}

	public synchronized Set<V> remove(K key) {
		return map.remove(key);
	}

	public synchronized V remove(K key, V value) {
		Set<V> vals = map.get(key);
		if (vals == null)
			return null;
		vals.remove(value);
		return value;
	}

	public synchronized void putAll(Map<K, V> m) {
		Set<Entry<K, V>> ens = m.entrySet();
		for (Entry<K, V> e : ens) {
			put(e.getKey(), e.getValue());
		}
	}

	public synchronized void clear() {
		map.clear();
	}

	public synchronized Set<K> keySet() {
		return map.keySet();
	}

	public synchronized Collection<Set<V>> values() {
		return map.values();
	}

	public synchronized Set<Entry<K, Set<V>>> entrySet() {
		return map.entrySet();
	}

}
